"""
无人机通信协议模块 - 实现基于时延感知与双重优先级的无人机飞联网传输协议(DCDP)和传统协议
"""

import time
import random
import numpy as np
from enum import Enum
import config
from message import Message, AcknowledgementMessage

class ProtocolType(Enum):
    """协议类型枚举"""
    BASIC_TRADITIONAL = 0  # 基础传统协议
    ZIGBEE = 1             # ZigBee协议
    WIFI_DIRECT = 2        # WiFi Direct协议
    LORA = 3               # LoRa协议
    FANET = 4              # Flying Ad-hoc Network协议
    DCDP_PROTOCOL = 5      # 基于时延感知与双重优先级的无人机飞联网传输协议(DCDP)

class CommunicationProtocol:
    """通信协议基类"""
    
    def __init__(self, protocol_type):
        """
        初始化通信协议
        
        参数:
            protocol_type: 协议类型
        """
        self.type = protocol_type
        self.packet_loss_rate = config.PACKET_LOSS_RATE
        self.base_delay = config.BASE_DELAY
        self.bandwidth = config.BANDWIDTH
        
        # 性能统计
        self.stats = {
            'sent_packets': 0,
            'received_packets': 0,
            'lost_packets': 0,
            'retransmissions': 0,
            'avg_delay': 0,
            'total_delay': 0,
            'missed_deadlines': 0,
            'emergency_messages_handled': 0
        }
    
    def calculate_transmission_delay(self, message, link_quality=1.0):
        """
        计算传输延迟
        
        参数:
            message: 要传输的消息
            link_quality: 链路质量 (0-1)
            
        返回:
            延迟时间(毫秒)
        """
        # 基础延迟
        delay = self.base_delay
        
        # 加上根据消息大小和带宽计算的传输延迟
        transmission_delay = (message.size * 8) / (self.bandwidth * 1024 * 1024) * 1000  # 毫秒
        delay += transmission_delay
        
        # 考虑链路质量影响 (质量越差，延迟越高)
        quality_factor = 1 + (1 - link_quality) * 2
        delay *= quality_factor
        
        # 添加一些随机波动
        jitter = random.uniform(-0.1, 0.1) * delay
        delay += jitter
        
        return max(1, delay)  # 最小延迟为1毫秒
    
    def simulate_packet_loss(self, link_quality=1.0):
        """
        模拟丢包
        
        参数:
            link_quality: 链路质量 (0-1)
            
        返回:
            布尔值，True表示发生丢包
        """
        # 链路质量影响丢包率 (质量越差，丢包率越高)
        effective_loss_rate = self.packet_loss_rate + (1 - link_quality) * 0.2
        return random.random() < effective_loss_rate
    
    def send_message(self, sender, receiver, message, current_time):
        """
        发送消息 (基类方法，需要在子类中实现)
        
        参数:
            sender: 发送方无人机
            receiver: 接收方无人机
            message: 要发送的消息
            current_time: 当前仿真时间
            
        返回:
            (布尔值, 延迟) 元组，表示是否发送成功及传输延迟
        """
        raise NotImplementedError("必须在子类中实现")
    
    def update_stats(self, success, delay=None, is_emergency=False, deadline_missed=False):
        """
        更新性能统计
        
        参数:
            success: 是否成功传输
            delay: 传输延迟 (毫秒)
            is_emergency: 是否为紧急消息
            deadline_missed: 是否错过截止时间
        """
        if success:
            self.stats['received_packets'] += 1
            if delay is not None:
                self.stats['total_delay'] += delay
                self.stats['avg_delay'] = self.stats['total_delay'] / self.stats['received_packets']
                
            if is_emergency:
                self.stats['emergency_messages_handled'] += 1
        else:
            self.stats['lost_packets'] += 1
            
        if deadline_missed:
            self.stats['missed_deadlines'] += 1
            
        self.stats['sent_packets'] += 1

class TraditionalProtocol(CommunicationProtocol):
    """基础传统通信协议实现"""
    
    def __init__(self):
        """初始化传统协议"""
        super().__init__(ProtocolType.BASIC_TRADITIONAL)
        self.timeout = config.TRADITIONAL_TIMEOUT
        self.ack_timeout = config.TRADITIONAL_ACK_TIMEOUT
        self.frame_size = config.TRADITIONAL_FRAME_SIZE
    
    def send_message(self, sender, receiver, message, current_time):
        """
        使用传统协议发送消息
        
        参数:
            sender: 发送方无人机
            receiver: 接收方无人机
            message: 要发送的消息
            current_time: 当前仿真时间
            
        返回:
            (布尔值, 延迟) 元组，表示是否发送成功及传输延迟
        """
        # 获取链路质量
        link_quality = sender.link_quality.get(receiver.id, 0.5)
        
        # 标记消息为已发送
        message.mark_sent()
        
        # 模拟丢包
        if self.simulate_packet_loss(link_quality):
            self.update_stats(False, is_emergency=(message.type == 'EMERGENCY'))
            return False, 0
        
        # 计算传输延迟
        delay = self.calculate_transmission_delay(message, link_quality)
        
        # 传统协议没有优先级处理，所有消息平等对待
        # 检查是否超过截止时间
        deadline_missed = delay > message.deadline
        
        # 更新统计
        self.update_stats(
            True, 
            delay, 
            is_emergency=(message.type == 'EMERGENCY'),
            deadline_missed=deadline_missed
        )
        
        # 消息成功传输
        message.mark_received()
        
        return True, delay

class ZigBeeProtocol(CommunicationProtocol):
    """ZigBee协议实现 - 低功耗、低数据率的无线网络协议"""
    
    def __init__(self):
        """初始化ZigBee协议"""
        super().__init__(ProtocolType.ZIGBEE)
        self.timeout = config.TRADITIONAL_TIMEOUT * 1.2  # ZigBee延迟略高
        self.ack_timeout = config.TRADITIONAL_ACK_TIMEOUT * 1.2
        self.frame_size = 128  # ZigBee帧较小
        self.max_range = 100   # 较短的通信范围 (m)
        self.power_consumption = 0.5  # 较低的功耗 (相对单位)
        
    def send_message(self, sender, receiver, message, current_time):
        """
        使用ZigBee协议发送消息
        
        参数:
            sender: 发送方无人机
            receiver: 接收方无人机
            message: 要发送的消息
            current_time: 当前仿真时间
            
        返回:
            (布尔值, 延迟) 元组，表示是否发送成功及传输延迟
        """
        # 获取链路质量
        link_quality = sender.link_quality.get(receiver.id, 0.5)
        
        # 距离检查 - ZigBee通信范围有限
        distance = np.linalg.norm(sender.position - receiver.position)
        if distance > self.max_range:
            self.update_stats(False, is_emergency=(message.type == 'EMERGENCY'))
            return False, 0
        
        # 标记消息为已发送
        message.mark_sent()
        
        # 模拟丢包 - ZigBee在干扰环境下稳定性较好
        if self.simulate_packet_loss(link_quality * 1.1):  # 稍微降低丢包率
            self.update_stats(False, is_emergency=(message.type == 'EMERGENCY'))
            return False, 0
        
        # 计算传输延迟 - ZigBee速率较低，但稳定性高
        base_delay = self.calculate_transmission_delay(message, link_quality)
        # ZigBee的特点是低速率，所以延迟较高
        delay = base_delay * 1.5
        
        # 检查是否超过截止时间
        deadline_missed = delay > message.deadline
        
        # 更新统计
        self.update_stats(
            True, 
            delay, 
            is_emergency=(message.type == 'EMERGENCY'),
            deadline_missed=deadline_missed
        )
        
        # 消息成功传输
        message.mark_received()
        
        return True, delay

class WiFiDirectProtocol(CommunicationProtocol):
    """WiFi Direct协议实现 - 高带宽但功耗较高的协议"""
    
    def __init__(self):
        """初始化WiFi Direct协议"""
        super().__init__(ProtocolType.WIFI_DIRECT)
        self.timeout = config.TRADITIONAL_TIMEOUT * 0.7  # WiFi Direct速度较快
        self.ack_timeout = config.TRADITIONAL_ACK_TIMEOUT * 0.7
        self.frame_size = 1500  # 较大的帧大小
        self.max_range = 200    # 较长的通信范围 (m)
        self.power_consumption = 2.0  # 较高的功耗 (相对单位)
        
    def send_message(self, sender, receiver, message, current_time):
        """
        使用WiFi Direct协议发送消息
        
        参数:
            sender: 发送方无人机
            receiver: 接收方无人机
            message: 要发送的消息
            current_time: 当前仿真时间
            
        返回:
            (布尔值, 延迟) 元组，表示是否发送成功及传输延迟
        """
        # 获取链路质量
        link_quality = sender.link_quality.get(receiver.id, 0.5)
        
        # 距离检查 - WiFi Direct范围适中
        distance = np.linalg.norm(sender.position - receiver.position)
        if distance > self.max_range:
            self.update_stats(False, is_emergency=(message.type == 'EMERGENCY'))
            return False, 0
        
        # 标记消息为已发送
        message.mark_sent()
        
        # 模拟丢包 - WiFi Direct在干扰时丢包率较高
        if self.simulate_packet_loss(link_quality * 0.8):  # 增加丢包率
            self.update_stats(False, is_emergency=(message.type == 'EMERGENCY'))
            return False, 0
        
        # 计算传输延迟 - WiFi Direct速率高，延迟低
        base_delay = self.calculate_transmission_delay(message, link_quality)
        # WiFi Direct的特点是高速率
        delay = base_delay * 0.6
        
        # 检查是否超过截止时间
        deadline_missed = delay > message.deadline
        
        # 更新统计
        self.update_stats(
            True, 
            delay, 
            is_emergency=(message.type == 'EMERGENCY'),
            deadline_missed=deadline_missed
        )
        
        # 消息成功传输
        message.mark_received()
        
        return True, delay

class LoRaProtocol(CommunicationProtocol):
    """LoRa协议实现 - 长距离低功耗，但低数据率"""
    
    def __init__(self):
        """初始化LoRa协议"""
        super().__init__(ProtocolType.LORA)
        self.timeout = config.TRADITIONAL_TIMEOUT * 2.5  # LoRa速度极慢
        self.ack_timeout = config.TRADITIONAL_ACK_TIMEOUT * 2.5
        self.frame_size = 64   # 极小的帧大小
        self.max_range = 500   # 极长的通信范围 (m)
        self.power_consumption = 0.2  # 极低的功耗 (相对单位)
        
    def send_message(self, sender, receiver, message, current_time):
        """
        使用LoRa协议发送消息
        
        参数:
            sender: 发送方无人机
            receiver: 接收方无人机
            message: 要发送的消息
            current_time: 当前仿真时间
            
        返回:
            (布尔值, 延迟) 元组，表示是否发送成功及传输延迟
        """
        # 获取链路质量
        link_quality = sender.link_quality.get(receiver.id, 0.5)
        
        # 距离检查 - LoRa通信范围极长
        distance = np.linalg.norm(sender.position - receiver.position)
        if distance > self.max_range:
            self.update_stats(False, is_emergency=(message.type == 'EMERGENCY'))
            return False, 0
        
        # 标记消息为已发送
        message.mark_sent()
        
        # 模拟丢包 - LoRa在长距离通信时可靠性高
        if self.simulate_packet_loss(link_quality * 1.3):  # 显著降低丢包率
            self.update_stats(False, is_emergency=(message.type == 'EMERGENCY'))
            return False, 0
        
        # 检查消息大小 - LoRa适合小消息
        size_factor = min(5.0, max(1.0, message.size / 100))  # 消息大小对延迟的影响
        
        # 计算传输延迟 - LoRa速率极低，适合小消息长距离传输
        base_delay = self.calculate_transmission_delay(message, link_quality)
        # LoRa的特点是超低速率，延迟极高
        delay = base_delay * 3.0 * size_factor
        
        # 检查是否超过截止时间
        deadline_missed = delay > message.deadline
        
        # 更新统计
        self.update_stats(
            True, 
            delay, 
            is_emergency=(message.type == 'EMERGENCY'),
            deadline_missed=deadline_missed
        )
        
        # 消息成功传输
        message.mark_received()
        
        return True, delay

class FANETProtocol(CommunicationProtocol):
    """FANET协议实现 - 专为飞行特性优化的Ad-hoc网络协议"""
    
    def __init__(self):
        """初始化FANET协议"""
        super().__init__(ProtocolType.FANET)
        self.timeout = config.TRADITIONAL_TIMEOUT * 0.9
        self.ack_timeout = config.TRADITIONAL_ACK_TIMEOUT * 0.9
        self.frame_size = 512  # 中等帧大小
        self.max_range = 300   # 较长的通信范围 (m)
        self.power_consumption = 1.5  # 中等功耗 (相对单位)
        self.mobility_factor = 0.8   # 移动性适应因子 (越低越能适应高移动性)
        
    def send_message(self, sender, receiver, message, current_time):
        """
        使用FANET协议发送消息
        
        参数:
            sender: 发送方无人机
            receiver: 接收方无人机
            message: 要发送的消息
            current_time: 当前仿真时间
            
        返回:
            (布尔值, 延迟) 元组，表示是否发送成功及传输延迟
        """
        # 获取链路质量
        link_quality = sender.link_quality.get(receiver.id, 0.5)
        
        # 距离检查
        distance = np.linalg.norm(sender.position - receiver.position)
        if distance > self.max_range:
            self.update_stats(False, is_emergency=(message.type == 'EMERGENCY'))
            return False, 0
        
        # 考虑移动性的影响 - FANET专门为高移动性场景设计
        rel_velocity = np.linalg.norm(sender.velocity - receiver.velocity)
        mobility_impact = 1 + (rel_velocity * self.mobility_factor / 10)  # 相对速度对通信的影响
        
        # 标记消息为已发送
        message.mark_sent()
        
        # 模拟丢包 - FANET对移动性适应较好
        adjusted_loss_rate = self.packet_loss_rate / mobility_impact
        if random.random() < adjusted_loss_rate:
            self.update_stats(False, is_emergency=(message.type == 'EMERGENCY'))
            return False, 0
        
        # 计算传输延迟 - FANET针对无人机移动特性优化
        base_delay = self.calculate_transmission_delay(message, link_quality)
        # 调整延迟，考虑移动性
        delay = base_delay * 0.9 / mobility_impact
        
        # 检查是否超过截止时间
        deadline_missed = delay > message.deadline
        
        # 更新统计
        self.update_stats(
            True, 
            delay, 
            is_emergency=(message.type == 'EMERGENCY'),
            deadline_missed=deadline_missed
        )
        
        # 消息成功传输
        message.mark_received()
        
        return True, delay

class DCDPProtocol(CommunicationProtocol):
    """基于时延感知与双重优先级的无人机飞联网传输协议(DCDP)实现"""
    
    def __init__(self):
        """初始化DCDP协议"""
        super().__init__(ProtocolType.DCDP_PROTOCOL)
        self.timeout = config.FLY_PROTOCOL_TIMEOUT
        self.ack_timeout = config.FLY_PROTOCOL_ACK_TIMEOUT
        self.priority_levels = config.FLY_PROTOCOL_PRIORITY_LEVELS
        self.frame_size = config.FLY_PROTOCOL_FRAME_SIZE
        
        # 优先级队列处理
        self.priority_queues = [[] for _ in range(self.priority_levels)]
        
        # 链路状态表
        self.link_state_table = {}
        
        # 通信性能预测模型
        self.performance_prediction = {}
        
        # 时延模型参数
        self.queue_history = {}  # 记录队列历史，用于排队时延预测
        self.process_delay_factor = 0.05  # 处理时延因子，作为传输时延的比例
        self.mobility_impact_factor = 0.8  # 移动影响因子
        
        # 时延历史记录 - 用于自适应调整
        self.delay_history = {
            'transmission': [],  # 传输时延历史
            'queuing': [],       # 排队时延历史
            'processing': []     # 处理时延历史
        }
        
        # 每种消息类型的优先级映射
        self.message_type_priority = {
            'EMERGENCY': 0,      # 最高优先级
            'CONTROL': 1,
            'TELEMETRY': 2,
            'VIDEO': 3,
            'DATA': 4            # 最低优先级
        }
        
        # 预测模型权重
        self.prediction_weights = {
            'history': 0.3,      # 历史数据权重
            'current': 0.7       # 当前估计权重
        }
    
    def predict_transmission_delay(self, message, link_quality):
        """
        预测传输时延 - 与数据大小、带宽和链路质量相关
        
        参数:
            message: 要传输的消息
            link_quality: 链路质量
            
        返回:
            预测的传输时延(毫秒)
        """
        # 基本传输时延计算
        data_size_bits = message.size * 8  # 比特数
        bandwidth_bps = self.bandwidth * 1024 * 1024  # bps
        base_delay = (data_size_bits / bandwidth_bps) * 1000  # 毫秒
        
        # 考虑链路质量的影响 - 链路质量越差，传输时延越长
        quality_factor = 2 - link_quality  # 1.0(最好)到2.0(最差)
        transmission_delay = base_delay * quality_factor
        
        # 考虑传输距离的影响
        # 距离只影响信号强度，而信号强度已经在链路质量中体现
        
        # 记录历史预测结果
        self.delay_history['transmission'].append(transmission_delay)
        if len(self.delay_history['transmission']) > 50:
            self.delay_history['transmission'].pop(0)
        
        return transmission_delay
    
    def predict_queuing_delay(self, sender_id, message_priority):
        """
        预测排队时延 - 与发送方队列长度和消息优先级相关
        
        参数:
            sender_id: 发送方ID
            message_priority: 消息优先级
            
        返回:
            预测的排队时延(毫秒)
        """
        # 如果没有该发送方的历史记录，初始化
        if sender_id not in self.queue_history:
            self.queue_history[sender_id] = {
                'avg_queue_length': 0,
                'avg_service_time': 10,  # 假设平均服务时间为10ms
                'last_update': time.time(),
                'priority_factors': [1.0, 0.8, 0.6, 0.4, 0.2]  # 不同优先级的服务因子
            }
        
        history = self.queue_history[sender_id]
        
        # 根据优先级计算服务因子 - 优先级越高，服务因子越小
        service_factor = history['priority_factors'][min(message_priority, len(history['priority_factors'])-1)]
        
        # 计算排队时延 - 简化的M/M/1队列模型
        # 排队时延 = 平均队列长度 * 平均服务时间 * 服务因子
        queuing_delay = history['avg_queue_length'] * history['avg_service_time'] * service_factor
        
        # 记录历史预测结果
        self.delay_history['queuing'].append(queuing_delay)
        if len(self.delay_history['queuing']) > 50:
            self.delay_history['queuing'].pop(0)
        
        return queuing_delay
    
    def predict_processing_delay(self, message):
        """
        预测处理时延 - 与消息复杂度和计算资源相关
        
        参数:
            message: 要处理的消息
            
        返回:
            预测的处理时延(毫秒)
        """
        # 简化模型：处理时延与消息大小成正比
        base_processing_delay = message.size * self.process_delay_factor
        
        # 考虑消息类型的影响 - 不同类型消息处理复杂度不同
        type_factor = 1.0
        if message.type == 'EMERGENCY':
            type_factor = 0.8  # 紧急消息处理优化
        elif message.type == 'VIDEO':
            type_factor = 1.2  # 视频消息处理复杂
        
        processing_delay = base_processing_delay * type_factor
        
        # 记录历史预测结果
        self.delay_history['processing'].append(processing_delay)
        if len(self.delay_history['processing']) > 50:
            self.delay_history['processing'].pop(0)
        
        return processing_delay
    
    def predict_total_delay(self, sender, receiver, message):
        """
        预测总时延 = 传输时延 + 排队时延 + 处理时延
        
        参数:
            sender: 发送方无人机
            receiver: 接收方无人机
            message: 要传输的消息
            
        返回:
            预测的总时延(毫秒)
        """
        # 获取链路质量
        link_quality = sender.link_quality.get(receiver.id, 0.5)
        
        # 获取消息优先级
        effective_priority = min(self.priority_levels-1, 
                                self.message_type_priority.get(message.type, self.priority_levels-1))
        
        # 预测三类时延
        transmission_delay = self.predict_transmission_delay(message, link_quality)
        queuing_delay = self.predict_queuing_delay(sender.id, effective_priority)
        processing_delay = self.predict_processing_delay(message)
        
        # 计算总时延
        total_delay = transmission_delay + queuing_delay + processing_delay
        
        # 考虑移动性的影响
        relative_speed = np.linalg.norm(sender.velocity - receiver.velocity)
        mobility_factor = 1 + (relative_speed * self.mobility_impact_factor / 10)
        total_delay *= mobility_factor
        
        # 优先级调整 - 高优先级消息获得时延减免
        priority_discount = 1.0 - (0.1 * (self.priority_levels - 1 - effective_priority))
        total_delay *= max(0.5, priority_discount)
        
        return total_delay
    
    def update_link_state(self, uav_id1, uav_id2, quality):
        """
        更新链路状态表
        
        参数:
            uav_id1: 无人机1的ID
            uav_id2: 无人机2的ID
            quality: 链路质量
        """
        key = tuple(sorted([uav_id1, uav_id2]))
        self.link_state_table[key] = {
            'quality': quality,
            'last_update': time.time(),
            'stability': min(1.0, self.link_state_table.get(key, {}).get('stability', 0.5) + 0.1),
            'delay_history': self.link_state_table.get(key, {}).get('delay_history', [])
        }
        
        # 更新队列历史
        if uav_id1 not in self.queue_history:
            self.queue_history[uav_id1] = {
                'avg_queue_length': 0,
                'avg_service_time': 10,
                'last_update': time.time(),
                'priority_factors': [1.0, 0.8, 0.6, 0.4, 0.2]
            }
        
        if uav_id2 not in self.queue_history:
            self.queue_history[uav_id2] = {
                'avg_queue_length': 0,
                'avg_service_time': 10,
                'last_update': time.time(),
                'priority_factors': [1.0, 0.8, 0.6, 0.4, 0.2]
            }
    
    def predict_performance(self, sender_id, receiver_id, message_type):
        """
        预测通信性能
        
        参数:
            sender_id: 发送方无人机ID
            receiver_id: 接收方无人机ID
            message_type: 消息类型
            
        返回:
            预测的通信性能参数
        """
        key = tuple(sorted([sender_id, receiver_id]))
        link_state = self.link_state_table.get(key, {'quality': 0.5, 'stability': 0.5})
        
        # 获取消息优先级
        message_priority = self.message_type_priority.get(message_type, self.priority_levels-1)
        
        # 根据链路质量和稳定性预测性能
        prediction = {
            'expected_delay': 0,  # 将在后面计算
            'success_probability': link_state['quality'] * link_state['stability'],
            'priority_adjustment': 0
        }
        
        # 预测时延
        # 简化：因为没有完整的消息对象，这里只用简单估计
        dummy_message = type('DummyMessage', (), {'size': 1024, 'type': message_type})
        
        # 创建简单的sender和receiver对象用于预测
        dummy_sender = type('DummySender', (), {
            'id': sender_id, 
            'link_quality': {receiver_id: link_state['quality']},
            'velocity': np.array([0, 0, 0])
        })
        dummy_receiver = type('DummyReceiver', (), {
            'id': receiver_id,
            'velocity': np.array([0, 0, 0])
        })
        
        # 预测时延
        predicted_delay = self.predict_total_delay(
            dummy_sender, 
            dummy_receiver, 
            dummy_message
        )
        
        prediction['expected_delay'] = predicted_delay
        
        # 对紧急消息进行优先级调整
        if message_type == 'EMERGENCY':
            prediction['priority_adjustment'] = -1  # 提高优先级
            
        return prediction
    
    def send_message(self, sender, receiver, message, current_time):
        """
        使用DCDP协议发送消息
        
        参数:
            sender: 发送方无人机
            receiver: 接收方无人机
            message: 要发送的消息
            current_time: 当前仿真时间
            
        返回:
            (布尔值, 延迟) 元组，表示是否发送成功及传输延迟
        """
        # 获取链路质量
        link_quality = sender.link_quality.get(receiver.id, 0.5)
        
        # 更新链路状态
        self.update_link_state(sender.id, receiver.id, link_quality)
        
        # 预测性能
        performance = self.predict_performance(sender.id, receiver.id, message.type)
        
        # 获取消息的基本优先级
        base_priority = self.message_type_priority.get(message.type, self.priority_levels-1)
        
        # 优先级处理 - DCDP协议特性，双重优先级
        # 1. 消息类型优先级
        # 2. 动态优先级调整(基于时延感知)
        effective_priority = max(0, base_priority + performance['priority_adjustment'])
        
        # 时延预测 - 使用三类时延预测模型
        predicted_delay = self.predict_total_delay(sender, receiver, message)
        
        # 根据预测的时延和消息截止时间调整优先级
        # 如果预测时延接近截止时间，提高优先级
        urgency = predicted_delay / message.deadline
        if urgency > 0.8:  # 如果预测时延超过截止时间的80%
            urgency_adjustment = min(2, int(urgency * 2))  # 最多提高2级优先级
            effective_priority = max(0, effective_priority - urgency_adjustment)
        
        # 标记消息为已发送
        message.mark_sent()
        
        # DCDP协议针对高优先级消息降低丢包率
        # 丢包率随优先级递减，优先级0(最高)的丢包率最低
        loss_probability = self.packet_loss_rate * (1 - 0.15 * (self.priority_levels - 1 - effective_priority))
        
        # 模拟丢包
        if random.random() < loss_probability * (1 - link_quality):
            self.update_stats(False, is_emergency=(message.type == 'EMERGENCY'))
            # 更新队列长度信息
            if sender.id in self.queue_history:
                self.queue_history[sender.id]['avg_queue_length'] = max(0, self.queue_history[sender.id]['avg_queue_length'] - 0.1)
            return False, 0
        
        # 应用真实的时延模型
        # 1. 传输时延
        transmission_delay = self.predict_transmission_delay(message, link_quality)
        
        # 2. 排队时延 - 因为我们在仿真中简化了队列处理，这里使用预测值
        queuing_delay = self.predict_queuing_delay(sender.id, effective_priority)
        
        # 3. 处理时延
        processing_delay = self.predict_processing_delay(message)
        
        # 计算总时延
        total_delay = transmission_delay + queuing_delay + processing_delay
        
        # 应用优先级因子 - 优先级越高，时延越低
        priority_factor = 1.0 - (0.1 * (self.priority_levels - 1 - effective_priority))
        delay = total_delay * priority_factor
        
        # 检查是否超过截止时间
        deadline_missed = delay > message.deadline
        
        # 如果是紧急消息且可能错过截止时间，尝试加速传输
        if message.type == 'EMERGENCY' and delay > message.deadline * 0.8:
            delay *= 0.7  # 紧急加速
            deadline_missed = delay > message.deadline
        
        # 更新统计
        self.update_stats(
            True, 
            delay, 
            is_emergency=(message.type == 'EMERGENCY'),
            deadline_missed=deadline_missed
        )
        
        # 更新队列长度信息 - 成功传输后队列会变短
        if sender.id in self.queue_history:
            # 平滑更新
            current_length = self.queue_history[sender.id]['avg_queue_length']
            # 假设队列长度至少为1(当前消息)，最多减少1个消息
            self.queue_history[sender.id]['avg_queue_length'] = max(0, current_length - 1)
            
            # 更新服务时间估计
            current_service = self.queue_history[sender.id]['avg_service_time']
            new_service = (current_service * 0.9) + (delay * 0.1)  # 平滑更新
            self.queue_history[sender.id]['avg_service_time'] = new_service
        
        # 更新链路状态表中的延迟历史
        key = tuple(sorted([sender.id, receiver.id]))
        if key in self.link_state_table:
            delay_history = self.link_state_table[key].get('delay_history', [])
            delay_history.append(delay)
            if len(delay_history) > 20:  # 保留最近20条记录
                delay_history.pop(0)
            self.link_state_table[key]['delay_history'] = delay_history
        
        # 消息成功传输
        message.mark_received()
        
        return True, delay
    
    def route_message(self, uav_network, message, current_time):
        """
        路由消息 (DCDP协议的高级功能)
        
        参数:
            uav_network: 无人机网络
            message: 要路由的消息
            current_time: 当前仿真时间
            
        返回:
            最佳路径列表
        """
        sender_id = message.sender_id
        target_id = message.receiver_id
        
        # 如果是广播消息，返回空路径
        if target_id is None:
            return []
        
        # 建立网络图
        graph = {}
        for uav in uav_network:
            graph[uav.id] = {}
            for neighbor_id in uav.neighbors:
                link_key = tuple(sorted([uav.id, neighbor_id]))
                link_state = self.link_state_table.get(link_key, {'quality': 0.5})
                # 使用链路质量作为边的权重 (1/质量，因为质量越高权重应越低)
                graph[uav.id][neighbor_id] = 1 / max(0.1, link_state['quality'])
        
        # 使用Dijkstra算法找到最短路径
        distances = {node: float('infinity') for node in graph}
        distances[sender_id] = 0
        unvisited = list(graph.keys())
        predecessor = {node: None for node in graph}
        
        while unvisited:
            current = min(unvisited, key=lambda node: distances[node])
            
            if current == target_id:
                break
                
            if distances[current] == float('infinity'):
                break
                
            unvisited.remove(current)
            
            for neighbor, weight in graph[current].items():
                distance = distances[current] + weight
                if distance < distances[neighbor]:
                    distances[neighbor] = distance
                    predecessor[neighbor] = current
        
        # 重建路径
        path = []
        current = target_id
        while current:
            path.append(current)
            current = predecessor[current]
            
        # 反转路径以便从发送方到接收方
        path.reverse()
        
        # 确保路径从发送方开始，并且不为空
        return path if path and path[0] == sender_id else [] 